package com.example.demo.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.example.demo.entity.RoadConnect;
import com.example.demo.entity.TrafCross;
import com.example.demo.entity.TrafCrossDistance;
import com.example.demo.mapper.RoadConnectMapper;
import com.example.demo.mapper.TrafCrossMapper;
import com.example.demo.service.RoadConnectService;
import com.example.demo.service.TrafCrossService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.net.URI;
import java.util.*;

/**
 * @author ws
 * @since 2023-08-25
 */
@Service
public class TrafCrossServiceImpl implements TrafCrossService {
    @Autowired
    TrafCrossMapper trafCrossMapper;


    @Autowired
    RoadConnectMapper roadConnectMapper;
    @Override
    public List<TrafCross> getAllTrafCrosss() {
//        计算路口关系
//        getConnect();

        //根据路口关系查询路径
        getPath();
        return trafCrossMapper.getAllTrafCrosss();

    }

    @Override
    public TrafCross getTrafCrossById(Long crossNo) {
        return trafCrossMapper.getTrafCrossById(crossNo);
    }


    private void getPath() {
        //获取所有的路口关系
        List<RoadConnect> allRoadConnectCross = roadConnectMapper.getAllRoadConnectCross();

        //遍历每个路口，将路径查询出来
        for (RoadConnect roadConnectCross : allRoadConnectCross) {


            //fromCross
            Long fromCross = roadConnectCross.getFromCross();
            TrafCross trafCrossById = trafCrossMapper.getTrafCrossById(fromCross);
            BigDecimal longitute = trafCrossById.getLongitute();
            BigDecimal latitute = trafCrossById.getLatitute();

            if (longitute == null || latitute == null) {
                // 经纬度数据为空，进行处理（如直接排除）
                System.out.println("经纬度数据为空，进行处理（如直接排除）");
                continue;
            }
            if (longitute == null || latitute == null) {
                // 经纬度数据为空，进行处理（如直接排除）
                System.out.println("经纬度数据为空，进行处理（如直接排除）");
                continue;
            }
            if (latitute != null && (latitute.compareTo(BigDecimal.valueOf(-90)) < 0 || latitute.compareTo(BigDecimal.valueOf(90)) > 0)) {
                // 纬度超出有效范围，进行处理（如直接排除）
                System.out.println("经纬度数据为空，进行处理（如直接排除）");
                continue;
            }

            //toCross
            Long toCross = roadConnectCross.getToCross();
            TrafCross _trafCrossById = trafCrossMapper.getTrafCrossById(toCross);
            BigDecimal _longitute = _trafCrossById.getLongitute();
            BigDecimal _latitute = _trafCrossById.getLatitute();
            if (_longitute == null || _latitute == null) {
                // 经纬度数据为空，进行处理（如直接排除）
                System.out.println("经纬度数据为空，进行处理（如直接排除）");
                continue;
            }
            if (_longitute == null || _latitute == null) {
                // 经纬度数据为空，进行处理（如直接排除）
                System.out.println("经纬度数据为空，进行处理（如直接排除）");
                continue;
            }
            if (_latitute != null && (_latitute.compareTo(BigDecimal.valueOf(-90)) < 0 || _latitute.compareTo(BigDecimal.valueOf(90)) > 0)) {
                // 纬度超出有效范围，进行处理（如直接排除）
                System.out.println("经纬度数据为空，进行处理（如直接排除）");
                continue;
            }



            // 请求路网数据参数
            List<Map<String, Object>> postBody = new ArrayList<>();
            HashMap<String, Object> map = new HashMap<>();
            map.put("lon", longitute);
            map.put("lat", latitute);
            postBody.add(map);
            HashMap<String, Object> _map = new HashMap<>();
            _map.put("lon", _longitute);
            _map.put("lat", _latitute);
            postBody.add(_map);

            // 请求路网数据
            RestTemplate restTemplate = new RestTemplate();
            String postForObject = null;
            try {
                postForObject = restTemplate.postForObject("http://192.168.3.29:1025/route", postBody, String.class);
            } catch (RestClientException e) {
                e.printStackTrace();
                continue;
            }

            //查找二者路径信息，
            String pointList = JSONObject.parseObject(postForObject).getString("pointList");


            roadConnectCross.setPath(pointList);

        }
        roadConnectMapper.insertRoadConnectBatch1(allRoadConnectCross);

        System.out.println("更新数据");


    }


    public void getConnect() {
        //获取所有的路口
        List<TrafCross> allTrafCrosss = trafCrossMapper.getAllTrafCrosss();

        ArrayList<RoadConnect> roadConnects = new ArrayList<>();

        //寻找最近的5个路口，存入路口id
        for (TrafCross fromCross : allTrafCrosss) {
            System.out.println("----------");
            if (null==fromCross.getLatitute() || null==fromCross.getLongitute()
                   ) {
                continue;
            }

            ArrayList<TrafCrossDistance> trafCrossDistances = new ArrayList<>();

            for (TrafCross toCross : allTrafCrosss) {

                if (fromCross.getCrossNo().equals(toCross.getCrossNo())) {
                    continue; // 跳过同一路口
                }
                if (null==toCross.getLatitute() || null==toCross.getLongitute()) {
                    continue;
                }

                double distance = calculateDistance(fromCross, toCross);

                if (trafCrossDistances.size() < 5) {
                    trafCrossDistances.add(new TrafCrossDistance(toCross.getCrossNo(), distance));
                } else {
                    Collections.sort(trafCrossDistances,new ElementComparator());

                    TrafCrossDistance trafCrossDistance = trafCrossDistances.get(0);
                    TrafCrossDistance trafCrossDistance1 = trafCrossDistances.get(trafCrossDistances.size()-1);
                    if (distance < trafCrossDistances.get(trafCrossDistances.size() - 1).getDistance()) {
                        trafCrossDistances.remove(trafCrossDistances.size() - 1);
                        trafCrossDistances.add(new TrafCrossDistance(toCross.getCrossNo(), distance));
                    }
                }

            }


            for (TrafCrossDistance tcDistance : trafCrossDistances) {
                RoadConnect roadConnect = new RoadConnect();
                roadConnect.setFromCross(fromCross.getCrossNo());
                roadConnect.setToCross(tcDistance.getCrossNo());
                roadConnect.setDistance(String.valueOf(tcDistance.getDistance()));
                roadConnects.add(roadConnect);
            }
        }

        //将计算出的路口关系存储到数据库
        roadConnectMapper.insertRoadConnectBatch(roadConnects);


    }

    // 计算两个路口之间的距离（根据经纬度）
    private  double calculateDistance(TrafCross from, TrafCross to) {
        double lat1 = from.getLatitute().doubleValue();
        double lon1 = from.getLongitute().doubleValue();
        double lat2 = to.getLatitute().doubleValue();
        double lon2 = to.getLongitute().doubleValue();

        double earthRadius = 6371; // 地球半径，单位为千米

        double dLat = Math.toRadians(lat2 - lat1);
        double dLon = Math.toRadians(lon2 - lon1);

        double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
                + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2))
                * Math.sin(dLon / 2) * Math.sin(dLon / 2);

        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

        return earthRadius * c*1000; // 返回距离，单位为米
    }

    class  ElementComparator implements Comparator<TrafCrossDistance>{


        @Override
        public int compare(TrafCrossDistance o1, TrafCrossDistance o2) {
            return Double.compare(o1.getDistance(),o2.getDistance());
        }
    }
}
